package org.game.handler;

import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.common.dispatcher.ProtoDispatcher;
import org.common.netty.BaseNettyHandler;
import org.common.netty.Pack;
import org.common.netty.PackCodec;
import org.common.utils.SpringUtils;
import org.game.GameConfig;
import org.game.LoginServerManager;
import org.game.obj.LoginServerContext;
import org.protobuf.InnerServerMsg;
import org.protobuf.ProtoEnumMsg;

import java.net.InetSocketAddress;
import java.nio.channels.ClosedChannelException;

/**
 * GameServer连接登录服的NettyHandler
 * 主要做两件事
 * 1. 连接上登录服后主动推送本服务的信息进行注册
 * 2. 定时ping一下登录服
 */
@Slf4j
public class GameToLoginNettyHandler extends BaseNettyHandler {

    private LoginServerContext loginServerContext;

    /**
     * 收到协议数据
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, byte[] msg) throws Exception {
        //TODO 转发到对应的Actor进行处理
        Pack decode = PackCodec.decode(msg);
        int cmdId = decode.getCmdId();
        if (cmdId == ProtoEnumMsg.CMD.ID.GAME_SERVER_REGISTER_VALUE) {
            // login返回到登录服的协议
            InnerServerMsg.L2GRegister g2LRegister = InnerServerMsg.L2GRegister.parseFrom(decode.getData());
            int serverId = g2LRegister.getServerId();
            LoginServerManager loginServerManager = SpringUtils.getBean(LoginServerManager.class);
            loginServerManager.registerLoginServer(serverId, ctx.channel());
            log.info("登录服服注册，serverId={}", serverId);
            loginServerContext = loginServerManager.getLoginServerContext(serverId);
            return;
        }
        // 注册login以后都走分发
        if (loginServerContext == null) {
            log.error("登录服尚未注册");
            return;
        }
        ProtoDispatcher dispatcher = SpringUtils.getBean(ProtoDispatcher.class);
        dispatcher.dispatch(cmdId, decode.getData(), loginServerContext);


    }


    /**
     * 建立连接
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
        String ip = address.getAddress().getHostAddress();
        log.info("连接登录服—成功:ip = {}", ip);
        //发送注册协议
        GameConfig gameConfig = SpringUtils.getBean(GameConfig.class);
        InnerServerMsg.G2LRegister.Builder builder = InnerServerMsg.G2LRegister.newBuilder();
        builder.setServerId(gameConfig.getServerId());
        Pack pack = new Pack(ProtoEnumMsg.CMD.ID.GAME_SERVER_REGISTER_VALUE, builder);
        ctx.writeAndFlush(PackCodec.encode(pack));
    }


    /**
     * 连接断开
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("连接断开");
        //TODO 定时重连
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof ClosedChannelException) {
            return;
        }
        cause.printStackTrace();
        ctx.close();
    }
}
